package cn.itcast.bos.web.action.base;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.bos.domain.base.Courier;
import cn.itcast.bos.service.base.CourierService;

@ParentPackage("json-default")
@Namespace("/")
@Controller
@Scope("prototype")
public class CourierAction extends ActionSupport  implements ModelDriven<Courier>{
    
	private Courier courier = new Courier();
	
	@Override
	public Courier getModel() {
		// TODO Auto-generated method stub
		return courier;
	}	
	//注入service属性
	@Autowired
	private CourierService courierService;
    	
	@Action(value="courier_save",results={@Result(name="success",location="./pages/base/courier.html",type="redirect")})
	public String save(){
		courierService.save(courier);
		return SUCCESS;
	}
	
	private Integer page;
	private Integer rows;

	public void setPage(Integer page) {
		this.page = page;
	}
	public void setRows(Integer rows) {
		this.rows = rows;
	}
	
	
	//	无条件分页查询
	@Action(value="courier_pageQuery",results={@Result(name="success",type="json")})
    public String pageQuery(){
		  /*1.可以使用CriteriaBuilder  
		isNotBlank(courier.getCourierNum)   如果快递员的工号不为空
		就进行快递员的工号查询  
		cb.equal(root.get("courierNum").as(String.class),courier.getCourierNum())；  返回的类型就是Predicate   就是构造一个条件
					
		2.进行公司的查询  模糊查询getCompany 				
		
		3.第三个条件  getType  进行快递员的类型查询 type=?*/
    	//封装pageable对象
    	Pageable pageable = new PageRequest(page -1, rows);
    	Specification<Courier> specification = new Specification<Courier>() {
          
			@Override
			public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				//将所有的条件添加到list集合中
				 List<Predicate> list = new ArrayList<>();
				
				//查询当前对象 对应的表   CourierNum查询的是快递员的工号  CourierNum= ?
				if(StringUtils.isNotBlank(courier.getCourierNum())){   //如果不为空 就做查询
					Predicate p1 = cb.equal(root.get("courierNum").as(String.class),courier.getCourierNum());
					list.add(p1);
				}
				
				//查询所属单位company   进行模糊查询  Company like %?%
				if(StringUtils.isNotBlank(courier.getCompany())){
					Predicate p2 = cb.like(root.get("company").as(String.class),"%"+courier.getCompany()+"%");
					list.add(p2);						
				}
				
				//查询快递员类型 type = ?
				if(StringUtils.isNotBlank(courier.getType())){
					Predicate p3 = cb.equal(root.get("type").as(String.class),courier.getType());
					list.add(p3);
				}
				
				
/*				4.多表查询（查询当前对象  关联对象 对应数据表）
				使用Courier(root) 关联Standard  join关联  上面使用root对象只能添加courier里面的条件 现在通过join 
				得到了standard 的root对象 可以对standard里面的列进行查询   root.join()
				构造standard.name like %?%			返回的是and    getStandard  收派标准
				用一个list集合 将4个条件添加到list里面*/				
				Join<Object, Object> standardRoot = root.join("standard",JoinType.INNER);
				if(courier.getStandard() != null  && StringUtils.isNotBlank(courier.getStandard().getName())){
				    Predicate p4 = cb.like(standardRoot.get("name").as(String.class),"%"+courier.getStandard().getName()+"%");
				    list.add(p4);
				}				
				
				//当有一个条件 添加到了list中 哪个if存在list就会有哪个属性对应的条件
				//数组要是Predicate类型   new Predicate 是一个泛型的作用  将集合转换成一个predicate类型的数组 0代表这个数组的长度 
				return cb.and(list.toArray(new Predicate[0]));
			}
    		
		};
    	//传入条件查询对象  和 分页查询对象   实现条件分页查询
    	Page<Courier>  pagedate = courierService.findPageDate(specification,pageable);
    	Map<String, Object> map = new HashMap<>();
    	map.put("total", pagedate.getTotalElements());
    	map.put("rows", pagedate.getContent());
    	ActionContext.getContext().getValueStack().push(map);    	
    	return SUCCESS;
    }
	
	
	
	//快递员的作废功能
	private String  ids;
	
	public void setIds(String ids) {
		this.ids = ids;
	}
	
	
	// 作废快递员
		@Action(value = "courier_delBatch", results = { @Result(name = "success", location = "./pages/base/courier.html", type = "redirect") })
		public String delBatch() {
			// 按,分隔ids
			String[] idArray = ids.split(",");
			// 调用业务层，批量作废
			courierService.delBatch(idArray);

			return SUCCESS;
		}

		
		
		//查询未关联的快递员
		@Action(value="courier_findnoassociation",results={@Result(name="success",type="json")})
		public String findnoassociation(){
		    List<Courier> list = courierService.findNoAssociation();
		    ActionContext.getContext().getValueStack().push(list);
			return SUCCESS;
		}
		
		
		
		
		
		
		
		
		 
	}
